package net.cl.db.handler;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import net.cl.db.ColumnProperties;
import net.cl.db.TableProperties;

public class RowHandler {

	protected static Object toObject(ResultSet rs) {
		if (rs == null)
			throw new NullPointerException("ResultSet is null.");
		try {
			Object obj = null;
			if (rs.next())
				obj = rs.getObject(1);
			closeResultSet(rs);
			return obj;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	protected static Map<String, Object> toMap(ResultSet rs) {
		if (rs == null)
			throw new NullPointerException("ResultSet is null.");
		try {
			ResultSetMetaData md = rs.getMetaData();
			int columnCount = md.getColumnCount();
			Map<String, Object> row = new LinkedHashMap<String, Object>(columnCount);
			if (rs.next()) {
				for (int i = 1; i <= columnCount; i++) {
					row.put(md.getColumnName(i), rs.getObject(i));
				}
			}
			closeResultSet(rs);
			return row;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	protected static List<Map<String, Object>> toList(ResultSet rs) {
		if (rs == null)
			throw new NullPointerException("ResultSet is null.");
		try {
			ResultSetMetaData md = rs.getMetaData();
			int columnCount = md.getColumnCount();
			List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
			Map<String, Object> row;
			while (rs.next()) {
				row = new LinkedHashMap<String, Object>(columnCount);
				for (int i = 1; i <= columnCount; i++) {
					row.put(md.getColumnName(i), rs.getObject(i));
				}
				list.add(row);
			}
			closeResultSet(rs);
			return list;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	protected static Object[][] toObjectArray(ResultSet rs) {
		if (rs == null)
			throw new NullPointerException("ResultSet is null.");
		try {
			ResultSetMetaData md = rs.getMetaData();
			int columnCount = md.getColumnCount();
			List<Object[]> list = new ArrayList<Object[]>();
			Object[] row;
			while (rs.next()) {
				row = new Object[columnCount];
				for (int i = 1; i <= columnCount; i++) {
					row[i - 1] = rs.getObject(i);
				}
				list.add(row);
			}
			closeResultSet(rs);
			Object[][] array = new Object[list.size()][];
			int i = 0;
			for (Object[] one : list) {
				array[i] = one;
				i++;
			}
			return array;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	protected static void closeResultSet(ResultSet rs) {
		try {
			if (rs != null) {
				rs.close();
				rs.getStatement().close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
			rs = null;
		}
	}
	
	public static TableProperties getTableProperties(ResultSet rs, String tableName) throws SQLException {
		ResultSetMetaData rmd = rs.getMetaData();
		int columnCount = rmd.getColumnCount();
		TableProperties table = new TableProperties(columnCount);
		String schemaName = null;
		if (tableName.indexOf(".") > -1) {
			schemaName = tableName.substring(0, tableName.indexOf(".") - 1);
			table.setSchemaName(schemaName);
		}
		table.setTableName(tableName);
		Map<String, String> map = new HashMap<String, String>();
		// DatabaseMetaData md = DBFactory.getConnection().getMetaData();
		// if (md.supportsGetGeneratedKeys()) {
		// ResultSet rs = md.getPrimaryKeys(null, schemaName, tableName);
		// while (rs.next())
		// map.put(rs.getString("COLUMN_NAME"), "");
		// ResultSetHandler.closeResultSet(rs);
		// }
		ColumnProperties[] cps = new ColumnProperties[columnCount];
		for (int i = 1; i <= columnCount; i++) {
			ColumnProperties cp = new ColumnProperties();
			cp.setColumnName(rmd.getColumnName(i));
			cp.setJdbcType(rmd.getColumnType(i));
			cp.setJdbcTypeName(rmd.getColumnTypeName(i));
			cp.setLength(rmd.getPrecision(i));
			cp.setScale(rmd.getScale(i));
			cp.setNullable(rmd.isNullable(i) != 0);
			cp.setAutoIncrement(rmd.isAutoIncrement(i));
			if (map.get(rmd.getColumnName(i)) != null)
				cp.setPrimaryKey(true);
			if (table.getDateFlag() == false
					&& (rmd.getColumnType(i) == Types.DATE || rmd.getColumnType(i) == Types.TIME || rmd
							.getColumnType(i) == Types.TIMESTAMP))
				table.setDateFlag(true);
			cps[i - 1] = cp;
		}
		table.setColumns(cps);
		return table;
	}

}
